import logging
from app.repository.course_repository import course_repository
from app.model.course_model import Course

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class CourseService:
    """课程服务类 - 提供课程管理的业务逻辑"""
    
    def __init__(self):
        """初始化课程服务"""
        self.repository = course_repository
    
    def create_course(self, name, credit):
        """创建新课程"""
        try:
            logger.info(f"尝试创建课程: 名称='{name}', 学分={credit}")
            
            # 业务逻辑：检查课程名称是否已存在
            existing_courses = self.repository.search_by_name(name)
            for course in existing_courses:
                if course.name == name:
                    logger.warning(f"课程创建失败：名称 '{name}' 已存在")
                    raise ValueError(f"课程名称 '{name}' 已存在")
            
            # 创建课程并保存
            course = Course(name=name, credit=credit)
            success = self.repository.save(course)
            
            if success:
                logger.info(f"课程创建成功: ID={course.id}, 名称='{course.name}'")
                return course
            else:
                logger.error(f"课程保存失败: 名称='{name}'")
                return None
        
        except ValueError as ve:
            # 处理业务逻辑错误
            logger.warning(f"业务逻辑错误: {str(ve)}")
            raise
        except Exception as e:
            # 处理其他未预期的错误
            logger.error(f"创建课程时发生未预期错误: {str(e)}", exc_info=True)
            raise RuntimeError(f"创建课程失败: {str(e)}")
    
    def get_course_by_id(self, course_id):
        """根据ID获取课程"""
        try:
            logger.info(f"尝试获取课程: ID={course_id}")
            course = self.repository.get_by_id(course_id)
            
            if not course:
                logger.warning(f"课程不存在: ID={course_id}")
                raise ValueError(f"课程ID {course_id} 不存在")
            
            logger.info(f"成功获取课程: ID={course.id}, 名称='{course.name}'")
            return course
        
        except ValueError as ve:
            logger.warning(f"业务逻辑错误: {str(ve)}")
            raise
        except Exception as e:
            logger.error(f"获取课程时发生未预期错误: {str(e)}", exc_info=True)
            raise RuntimeError(f"获取课程失败: {str(e)}")
    
    def get_all_courses(self):
        """获取所有课程"""
        try:
            logger.info("尝试获取所有课程")
            courses = self.repository.get_all()
            logger.info(f"成功获取所有课程，共 {len(courses)} 条记录")
            return courses
        
        except Exception as e:
            logger.error(f"获取所有课程时发生错误: {str(e)}", exc_info=True)
            raise RuntimeError(f"获取所有课程失败: {str(e)}")
    
    def update_course(self, course_id, name=None, credit=None):
        """更新课程信息"""
        try:
            logger.info(f"尝试更新课程: ID={course_id}, 名称='{name}', 学分={credit}")
            
            # 验证课程是否存在
            existing_course = self.repository.get_by_id(course_id)
            if not existing_course:
                logger.warning(f"课程更新失败：课程不存在，ID={course_id}")
                raise ValueError(f"课程ID {course_id} 不存在")
            
            # 如果更新名称，检查新名称是否与其他课程重复
            if name and name != existing_course.name:
                courses = self.repository.search_by_name(name)
                for course in courses:
                    if course.name == name and course.id != course_id:
                        logger.warning(f"课程更新失败：名称 '{name}' 已存在")
                        raise ValueError(f"课程名称 '{name}' 已存在")
            
            success = self.repository.update(course_id, name, credit)
            if success:
                logger.info(f"课程更新成功: ID={course_id}")
            else:
                logger.warning(f"课程更新失败: ID={course_id}")
            
            return success
        
        except ValueError as ve:
            logger.warning(f"业务逻辑错误: {str(ve)}")
            raise
        except Exception as e:
            logger.error(f"更新课程时发生未预期错误: {str(e)}", exc_info=True)
            raise RuntimeError(f"更新课程失败: {str(e)}")
    
    def delete_course(self, course_id):
        """删除课程"""
        try:
            logger.info(f"尝试删除课程: ID={course_id}")
            
            # 验证课程是否存在
            course = self.repository.get_by_id(course_id)
            if not course:
                logger.warning(f"课程删除失败：课程不存在，ID={course_id}")
                raise ValueError(f"课程ID {course_id} 不存在")
            
            # 这里可以添加额外的业务逻辑，比如检查是否有学生选修了这门课程
            # 例如：if self._has_enrolled_students(course_id): raise ValueError("该课程有学生选修，无法删除")
            
            success = self.repository.delete(course_id)
            if success:
                logger.info(f"课程删除成功: ID={course_id}")
            else:
                logger.warning(f"课程删除失败: ID={course_id}")
            
            return success
        
        except ValueError as ve:
            logger.warning(f"业务逻辑错误: {str(ve)}")
            raise
        except Exception as e:
            logger.error(f"删除课程时发生未预期错误: {str(e)}", exc_info=True)
            raise RuntimeError(f"删除课程失败: {str(e)}")
    
    def search_courses_by_name(self, keyword):
        """根据名称关键字搜索课程"""
        try:
            logger.info(f"尝试搜索课程: 关键字='{keyword}'")
            
            if not keyword or not keyword.strip():
                logger.info("搜索关键字为空，返回所有课程")
                return self.repository.get_all()
            
            courses = self.repository.search_by_name(keyword.strip())
            logger.info(f"搜索完成，找到 {len(courses)} 门匹配的课程")
            return courses
        
        except Exception as e:
            logger.error(f"搜索课程时发生错误: {str(e)}", exc_info=True)
            raise RuntimeError(f"搜索课程失败: {str(e)}")
    
    def get_courses_by_credit_range(self, min_credit, max_credit):
        """根据学分范围获取课程"""
        try:
            logger.info(f"尝试按学分范围获取课程: {min_credit}-{max_credit}")
            
            if min_credit > max_credit:
                logger.warning(f"学分范围无效: 最低学分({min_credit}) > 最高学分({max_credit})")
                raise ValueError("最低学分不能大于最高学分")
            
            all_courses = self.repository.get_all()
            filtered_courses = [course for course in all_courses 
                               if min_credit <= course.credit <= max_credit]
            
            logger.info(f"按学分范围筛选完成，找到 {len(filtered_courses)} 门课程")
            return filtered_courses
        
        except ValueError as ve:
            logger.warning(f"业务逻辑错误: {str(ve)}")
            raise
        except Exception as e:
            logger.error(f"按学分范围获取课程时发生错误: {str(e)}", exc_info=True)
            raise RuntimeError(f"获取课程失败: {str(e)}")

# 创建服务实例供外部使用
course_service = CourseService()